﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Adams.Shared
{
    public static class Validation
    {
        public static bool Empty(string value)
        {
            if (!string.IsNullOrEmpty(value) && value.Trim() != string.Empty)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public static bool Integer(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            int result = 0;
            if (int.TryParse(value, out result))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool Decimal(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            decimal result = 0;
            if (decimal.TryParse(value, out result))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool Currency(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            return Validation.RegEx(value, @"^\$?[0-9]+(,[0-9]{3})*(\.[0-9]{2})?$");
        }

        public static bool RegEx(string value, string expression)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(expression))
            {
                Regex reg = new Regex(expression);
                if (reg.IsMatch(value))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        public static bool Email(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            string expression = @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$";

            if (!string.IsNullOrEmpty(value))
            {
                Regex reg = new Regex(expression);
                if (reg.IsMatch(value))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        public static bool Date(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            DateTime result = DateTime.UtcNow;
            if (DateTime.TryParse(value, out result))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public enum CardType
        {
            MasterCard = 0x0001,
            VISA = 0x0002,
            Amex = 0x0004,
            DinersClub = 0x0008,
            enRoute = 0x0010,
            Discover = 0x0020,
            JCB = 0x0040,
            Unknown = 0x0080,
            All = CardType.Amex | CardType.DinersClub |
                             CardType.Discover | CardType.Discover |
                             CardType.enRoute | CardType.JCB |
                             CardType.MasterCard | CardType.VISA
        }

        public static bool CreditCard(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return true;
            }

            var _cardTypes = CardType.All;

            // AMEX -- 34 or 37 -- 15 length

            if ((Regex.IsMatch(value, "^(34|37)"))
                 && ((_cardTypes & CardType.Amex) != 0))
                return (15 == value.Length);

            // MasterCard -- 51 through 55 -- 16 length

            else if ((Regex.IsMatch(value, "^(51|52|53|54|55)")) &&
                      ((_cardTypes & CardType.MasterCard) != 0))
                return (16 == value.Length);

            // VISA -- 4 -- 13 and 16 length

            else if ((Regex.IsMatch(value, "^(4)")) &&
                      ((_cardTypes & CardType.VISA) != 0))
                return (13 == value.Length || 16 == value.Length);

            // Diners Club -- 300-305, 36 or 38 -- 14 length

            else if ((Regex.IsMatch(value, "^(300|301|302|303|304|305|36|38)")) &&
                      ((_cardTypes & CardType.DinersClub) != 0))
                return (14 == value.Length);

            // enRoute -- 2014,2149 -- 15 length

            else if ((Regex.IsMatch(value, "^(2014|2149)")) &&
                      ((_cardTypes & CardType.DinersClub) != 0))
                return (15 == value.Length);

            // Discover -- 6011 -- 16 length

            else if ((Regex.IsMatch(value, "^(6011)")) &&
                     ((_cardTypes & CardType.Discover) != 0))
                return (16 == value.Length);

            // JCB -- 3 -- 16 length

            else if ((Regex.IsMatch(value, "^(3)")) &&
                     ((_cardTypes & CardType.JCB) != 0))
                return (16 == value.Length);

            // JCB -- 2131, 1800 -- 15 length

            else if ((Regex.IsMatch(value, "^(2131|1800)")) &&
                       ((_cardTypes & CardType.JCB) != 0))
                return (15 == value.Length);
            else
            {
                // Card type wasn't recognised, provided Unknown is in the 

                // CardTypes property, then return true, otherwise return false.

                if ((_cardTypes & CardType.Unknown) != 0)
                    return true;
                else
                    return false;
            }
        }
    }
}
